package pattern.controller;

import cn.hutool.core.lang.Dict;
import cn.hutool.crypto.digest.DigestUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pattern.WorkServiceTool;
import pattern.annontations.Menu;
import pattern.annontations.Secure;
import pattern.common.abstractcontroller.AbstractSystemInfoController;
import pattern.common.system.Server;
import pattern.config.session.SessionCacheManage;
import pattern.constant.CacheKeyConstant;
import pattern.currentsession.ContextLocalCache;
import pattern.dto.Role;
import pattern.dto.SysDept;
import pattern.dto.User;
import pattern.dto.model.system.UserProfileEditModel;
import pattern.dto.model.system.UserPwdEditModel;
import pattern.dto.response.system.ProfileResponse;
import pattern.exception.AssertTool;
import pattern.model.BaseIdModel;
import pattern.result.ResponseData;
import pattern.result.ResponseResultStatus;
import pattern.routing.WorkMainApiRouting;
import pattern.utils.CollectionUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Simon
 * @date 2020-08-21
 */
@Api(tags = "通用接口")
@ApiSort(0)
@RestController
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Secure
@Slf4j
@RequestMapping(WorkMainApiRouting.Common.BASE)
public class CommonController extends AbstractSystemInfoController {

    private final SessionCacheManage sessionManage;

    @ApiOperation(value = "获取用户信息", tags = "角色管理")
    @GetMapping(WorkMainApiRouting.Common.GET_INFO)
    public ResponseData<Dict> getInfo() {
        Dict result = Dict.create();
        var context = ContextLocalCache.get();
        result.put("roles", context.getRoleId());
        result.put("image", context.getImage());
        result.put("userName", context.getUserName());
        result.put("phone", context.getPhone());
        if (CollectionUtil.isNotEmpty(context.getRoleId())) {
            result.put("menus", WorkServiceTool.getMenuOfRoleService().getPermissionsOfRoles(new BaseIdModel<>(context.getRoleId())));
            result.put("actions", WorkServiceTool.getActionOfRoleService().getPermissionsOfRoles(new BaseIdModel<>(context.getRoleId())));
        }
        return new ResponseData<>(result);
    }

    @ApiOperation(value = "登陆用户详情")
    @GetMapping(WorkMainApiRouting.Common.PROFILE)
    public ResponseData<ProfileResponse> profile() {
        var user = WorkServiceTool.getUserService().getById(new BaseIdModel<>(ContextLocalCache.get().getId()));
        ProfileResponse userResponse = new ProfileResponse().setUser(user);
        var roles = WorkServiceTool.getRoleService().list().stream().filter(e -> ContextLocalCache.get().getRoleId().contains(e.getId()))
                .map(Role::getRoleName).collect(Collectors.toList());
        userResponse.setRoles(roles);
        var sysDepts = WorkServiceTool.getCache().deptCache.get(CacheKeyConstant.SysDept.DEPT_KEY);
        var sysDept = sysDepts.stream().filter(e -> e.getId().equals(ContextLocalCache.get().getDeptId())).map(SysDept::getName).findFirst().orElse(null);
        userResponse.setDeptName(sysDept);
        return new ResponseData<>(userResponse);
    }

    @ApiOperation(value = "编辑登陆用户详情")
    @PutMapping(WorkMainApiRouting.Common.PROFILE)
    public ResponseData<Boolean> editProfile(@RequestBody @Valid UserProfileEditModel userProfileEditModel) {
        var id = WorkServiceTool.getUserService().updateById(userProfileEditModel);
        return new ResponseData<>(Objects.nonNull(id));
    }

    @ApiOperation(value = "修改登陆用户密码")
    @PutMapping(WorkMainApiRouting.Common.UPDATE_PWD)
    public ResponseData<Boolean> updatePwd(@RequestBody @Valid UserPwdEditModel model) {
        var user = WorkServiceTool.getUserService().getById(new BaseIdModel<>(ContextLocalCache.get().getId()));
        AssertTool.isTrue(DigestUtil.bcryptCheck(model.getOldPassword(), user.getPsw()), ResponseResultStatus.WRONG_PASSWORDS);
        User editUser = new User();
        editUser.setId(user.getId());
        editUser.setPsw(DigestUtil.bcrypt(model.getNewPassword()));
        var id = WorkServiceTool.getUserService().getBaseMapper().updateById(editUser);
        return new ResponseData<>(id > 0);
    }

    @ApiOperation(value = "修改登陆用户头像")
    @PutMapping(WorkMainApiRouting.Common.AVATAR)
    public ResponseData<String> avatar(@RequestBody Map<String,Object> map, HttpServletRequest request,HttpServletResponse response) {
        String imgUrl= (String) map.get("imgUrl");
        var patternContext = ContextLocalCache.get();
        var user = WorkServiceTool.getUserService().getById(new BaseIdModel<>(patternContext.getId()));
        User editUser = new User();
        editUser.setId(user.getId());
        editUser.setImage(imgUrl);
        WorkServiceTool.getUserService().getBaseMapper().updateById(editUser);
        sessionManage.refreshSessionToken(patternContext.getToken(), request, response,Boolean.TRUE);
        var responseData = new ResponseData<String>(ResponseResultStatus.SUCCESS);
        responseData.setData(imgUrl);
        return responseData;
    }

    @ApiOperation(value = "系统节点监控")
    @GetMapping(WorkMainApiRouting.Common.SERVER_INFO)
    @Menu(menuName = "system_info", menuUri = "system_info_monitor", foundational = false)
    public ResponseData<Server> serverInfo() throws Exception {
        return super.getServerInfo();
    }

    @ApiOperation(value = "缓存监控")
    @GetMapping(WorkMainApiRouting.Common.CACHE_INFO)
    @Menu(menuName = "cache_info", menuUri = "cache_info_monitor", foundational = false)
    public ResponseData<Map<String, Object>> cacheInfo(){
        return super.getCache();
    }
}
